﻿using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using gbL.NetBoard.Helpers;
using gbL.NetBoard.Examples.DoubleMVC.View.UI.Requests;
using gbL.NetBoard.Examples.DoubleMVC.View.UI.ViewModel;

namespace gbL.NetBoard.Examples.DoubleMVC.View.UI
{
    public class ListView : MultiTypedMessageListener
    {
        public IOutputTarget Output { get; set; }

        public ListView(Blackboard domain) : this(domain, new ConsoleOutputTarget()) { }

        public ListView(Blackboard domain, IOutputTarget output) : base(domain) { Output = output; }

        protected override void OnMessageAdded(object message)
        {
            if (message is ListViewRequest<ListProduct>) Process((ListViewRequest<ListProduct>)message);
        }

        protected override void OnMessageRemoved(object message)
        {
            //
        }

        protected override Type[] MessageTypes
        {
            get
            {
                return new[] { 
                    typeof(ListViewRequest<ListProduct>),
                    typeof(ListViewRequest<ListOrder>)
                };
            }
        }

        void Process(ListViewRequest<ListProduct> message)
        {
            var taken = Messages.Take(e => e.Message == message);
            if (taken.Count == 0) return;

            //Output.Clear();
            Output.WriteLine();

            List<ColumnDef<ListProduct>> columns = new List<ColumnDef<ListProduct>>(new[] {
                new ColumnDef<ListProduct>("ID", x => x.ID.ToString(), true),
                new ColumnDef<ListProduct>("Name", x => x.ProductName.ToString(), false),
                new ColumnDef<ListProduct>("Price", x => x.Price.ToString("#.00"), true)
            });

            OutputTable(columns, message.Results);
        }

        void Process(ListViewRequest<ListOrder> message)
        {
            var taken = Messages.Take(e => e.Message == message);
            if (taken.Count == 0) return;

            //Output.Clear();
            Output.WriteLine();

            List<ColumnDef<ListOrder>> columns = new List<ColumnDef<ListOrder>>(new[] {
                new ColumnDef<ListOrder>("ID", x => x.ID.ToString(), true),
                new ColumnDef<ListOrder>("Date", x => x.OrderDate.ToShortDateString(), true),
                new ColumnDef<ListOrder>("Customer", x => x.Customer, false),
                new ColumnDef<ListOrder>("Description", x => x.Description, false)
            });

            OutputTable(columns, message.Results);
        }

        void OutputTable<T>(List<ColumnDef<T>> columns, IEnumerable<T> dataItems)
        {
            foreach (var columnDef in columns)
            {
                columnDef.CalculateWidth(dataItems);
                columnDef.OutputTitleCell(Output);
            }

            Output.WriteLine();

            var lastColumn = columns[columns.Count - 1];

            foreach (T listProduct in dataItems)
            {
                foreach (var columnDef in columns)
                {
                    columnDef.OutputColumnCell(listProduct, Output, columnDef != lastColumn);
                }
                Output.WriteLine();
            }

        }
    }
}
